<template>
  <div class="vue-tabs-chrome">
    <div ref="content" class="tabs-content">
      <!-- tab 分割线 -->
      <div
        v-for="indexDivider in tabs.length"
        :key="indexDivider"
        class="tabs-divider"
        :style="{ left: (tabWidth - gap * 2) * indexDivider + gap + 'px' }"
      ></div>
      <!-- tab -->
      <div
        v-for="(tab, index) in tabs"
        :key="tab.id"
        ref="item"
        class="tabs-item"
        :class="
          [{ active: tab.id === value }, `tab-${tab.id}`, tab.class].filter(
            (item) => item
          )
        "
        :style="{
          width: tabWidth + 'px',
          left: (tabWidth - gap * 2) * index + 'px',
        }"
        @click="handleClickTab(tab)"
      >
        <!-- 背景样式 -->
        <div class="tabs-background">
          <!-- 样式 -->
          <div class="tabs-background-content"></div>
          <svg
            class="tabs-background-before"
            :style="{ width: '7px', height: '7px' }"
          >
            <path d="M 0 7 A 7 7 0 0 0 7 0 L 7 7 Z"></path>
          </svg>
          <svg
            class="tabs-background-after"
            :style="{ width: '7px', height: '7px' }"
          >
            <path d="M 0 0 A 7 7 0 0 0 7 7 L 0 7 Z"></path>
          </svg>
        </div>
        <!-- 关闭 按钮 -->
        <div
          v-if="allowedDelete"
          class="tabs-close"
          @click.stop="handleDelete(tab, index, $event)"
        >
          <svg
            class="tabs-close-icon"
            :style="{ width: '16px', height: '16px', stroke: '#595959' }"
          >
            <path d="M 4 4 L 12 12 M 12 4 L 4 12"></path>
          </svg>
        </div>
        <!-- tab label  -->
        <div class="tabs-main">
          <!-- 正常显示状态 -->
          <div v-if="editPipelineId !== tab.id" class="tabs-label">
            <a-tooltip placement="top" :mouse-enter-delay="0.5">
              <template slot="title">
                <span>{{ tab.userName }}</span>
              </template>
              <div
                class="tabs-label-text"
                @dblclick="editPipelineName(tab.id, tab.userName)"
              >
                {{ tab.userName }}
              </div>
            </a-tooltip>

            <!-- 编辑 icon -->
            <!-- <a-icon-font
              v-if="tab.id === value && allowedEdit"
              class="tab-name-edit-icon"
              type="iconicon-beifen6"
              @click="editPipelineName(tab.id, tab.userName)"
            /> -->
            <a-tooltip
              v-show="lockMode"
              placement="top"
              :mouse-enter-delay="0.5"
            >
              <template slot="title">
                <span>此画板不可编辑</span>
              </template>
              <a-icon-font
                v-if="tab.userName !== '我' || isLock"
                class="tab-lock-icon"
                type="iconsuoding"
              />
            </a-tooltip>
          </div>
          <!-- 编辑状态 -->
          <div v-else class="tabs-label-edit">
            <a-input
              v-model="activeEditPipelineName"
              v-focus
              type="text"
              size="small"
              @keyup.enter.native="$event.target.blur"
              @blur="editPipelineEnter(tab.id, index)"
            />
          </div>
        </div>
      </div>
      <!-- tabs 尾部 插槽 -->
      <div
        ref="after"
        class="tabs-after"
        :style="{ left: (tabWidth - gap * 2) * tabs.length + gap * 2 + 'px' }"
      >
        <a-tooltip placement="top" :mouse-enter-delay="1">
          <template slot="title">
            <span>添加</span>
          </template>
          <div class="add-tab" @click="createTab">
            <a-icon-font class="icon-font" type="iconjiahao" />
          </div>
        </a-tooltip>
      </div>
    </div>
    <!--    <div class="tabs-footer"></div>-->
  </div>
</template>

<script lang="ts">
/**
 * Tab component  删减版 无拖动(able to edit tab name)
 * @author Jinhui Hou
 */

import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import DataViewStore from '@/store/modules/dataview'

@Component({
  components: {},
  filters: {},
  directives: {
    focus: {
      inserted: (element: any) => {
        element.focus()
      },
    },
  },
})
export default class Tabs extends Vue {
  @Prop({ type: [String, Number], default: '' }) private value!: string | number // 当前 激活 tab pipelineId
  @Prop({ type: Array, default: () => [] }) private tabs!: Array<any> // 所有 tabs
  @Prop({ type: Number, default: 40 }) private minWidth!: number // tab 最小宽度
  @Prop({ type: Number, default: 245 }) private maxWidth!: number // tab 最大宽度
  @Prop({ type: Number, default: 7 }) private gap!: number // 暂时未知
  @Prop({ type: Boolean, default: false }) private insertToAfter!: boolean // 添加 tab 到当前 激活tab 后,
  @Prop({ type: Boolean, default: true }) private allowedEdit!: boolean // 可编辑
  @Prop({ type: Boolean, default: true }) private allowedDelete!: boolean // 可删除
  @Prop({ type: Boolean, default: true }) private lockMode!: boolean // 是否需要锁定模式

  private tabWidth: number = 0 // tab 宽度 需要实时计算
  private timer: any = null // 定时器
  private editPipelineId: string | number | null = null // 添加编辑功能
  private activeEditPipelineName: string = '' // 编辑的 tab name

  /**
   * Vue 生命周期  mounted
   */
  private mounted() {
    this.calcTabWidth()
    window.addEventListener('resize', this.handleResize)
  }

  /**
   * Vue 生命周期  destroyed
   */
  private destroyed() {
    window.removeEventListener('resize', this.handleResize)
  }

  public get tabsLength() {
    return this.tabs.length
  }

  public get isLock() {
    return DataViewStore.getLock
  }

  @Watch('tabsLength')
  private watchTabs() {
    this.doLayout()
  }

  /**
   * 计算 tab 的宽度
   */
  public calcTabWidth() {
    const { tabs, maxWidth, minWidth, gap } = this
    const $content = this.$refs.content as HTMLElement // 整个 tabs 容器
    const after = this.$refs.after as HTMLElement // 尾部插槽
    const afterWidth = after.getBoundingClientRect().width // 尾部插槽 div 的宽度
    if (!$content) {
      return Math.max(maxWidth, minWidth)
    } // 如果 tab 容器不存在， 返回一个最大值, 其实返回只是占位
    // tabs 容器的可用宽度 gap 是 圆角防止贴边的宽度 first tab 左侧， last tab 右侧 ， 最后 插槽右侧贴边  共3个
    const contentWidth = $content.clientWidth - gap * 3 - afterWidth
    let width = contentWidth / tabs.length // 计算宽度, 根据 可用宽度和 tabs 长度
    width += gap * 2 // 加两边优化圆角
    // 宽度边界限制
    if (width > maxWidth) {
      width = maxWidth
    }
    if (width < minWidth) {
      width = minWidth
    }
    this.tabWidth = width
    return null
  }

  /**
   * 重新 layout 排布
   */
  public doLayout() {
    this.calcTabWidth()
  }

  /**
   * 点击切换 tab
   */
  public handleClickTab(tab: any) {
    this.$emit('check', tab.id)
  }

  /**
   * 编辑 tab name
   * @param id
   * @param name
   */
  public editPipelineName(id: string | number, name: string) {
    if (this.value === id && this.allowedEdit) {
      this.activeEditPipelineName = name
      this.editPipelineId = id
    }
  }

  /**
   * 确认编辑 tab name
   * @param id
   * @param index
   */
  public async editPipelineEnter(id: string | number, index: number) {
    if (this.activeEditPipelineName.length > 0) {
      this.$emit('edit', id, this.activeEditPipelineName, index)
      this.editPipelineId = null
      this.activeEditPipelineName = ''
    } else {
      this.$message.warning('tab name 不能为空')
    }
  }

  /**
   * 删除 tab
   * @param tab
   * @param index
   * @param $event
   */
  public handleDelete(tab: any, index: number, $event: MouseEvent) {
    $event.stopPropagation()
    const { tabs, value } = this
    const activeIndex = tabs.findIndex((item) => item.id === value) // 当前激活 tab 索引
    // 前后 tab
    let after: any = null
    let before: any = null

    let activeIdAfterDelete: number | string | null = null
    // 删除的是当前激活的
    if (index === activeIndex) {
      after = tabs[index + 1]
      before = tabs[index - 1]
    } else {
      activeIdAfterDelete = this.value
    }
    // 删除后激活的 tab id
    if (after) {
      activeIdAfterDelete = after.id
    } else if (before) {
      activeIdAfterDelete = before.id
    } else if (tabs.length <= 1) {
      activeIdAfterDelete = null
    }
    // 通知父组件 删除
    this.$emit('remove', tab, index, activeIdAfterDelete)
  }

  /**
   * 删除 tab
   */
  // public async deleteTab(
  //   index: number,
  //   removeTabId: any,
  //   activeId: number | string | null
  // ) {
  //   const response: any = await GraphAnalysis.delGraphTab({
  //     projectId: this.projectId,
  //     graphId: removeTabId,
  //   })
  //   if (response.data.code === 100) {
  //     GraphAnalysis.setActiveTabId(activeId)
  //   }
  // }

  /**
   * 创建 tab
   */
  public async createTab() {
    // const response = await GraphAnalysis.addGraphTab(this.projectId)
    // if (response.data.code === 100) {
    //   GraphAnalysis.setActiveTabId(response.data.result.id)
    // }
    this.$emit('add')
  }

  /**
   * 改变窗口宽度 相应
   */
  public handleResize() {
    if (this.timer) {
      clearTimeout(this.timer)
    }
    this.timer = setTimeout(() => {
      this.doLayout()
    }, 50)
  }
}
</script>

<style lang="less" scoped>
/* tab 整体 */
.vue-tabs-chrome {
  background-color: #ededf4;
  height: 38px;
  padding-top: 4px;
  position: relative;
  width: 100%;

  /* tab 内容 */
  .tabs-content {
    height: 34px;
    overflow: hidden;
    position: relative;
  }

  /* divider tab 间的分割线 */
  .tabs-divider {
    border-right: 1px solid #a9adb0;
    height: 20px;
    left: 0;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
  }

  /* tab */
  .tabs-item {
    align-items: center;
    box-sizing: border-box;
    display: flex;
    height: 100%;
    position: absolute;
    transition: width 0ms;
    user-select: none;

    /* hover */
    &:hover {
      .tabs-background-content {
        background-color: #f2f3f5;
      }

      .tabs-background-before,
      .tabs-background-after {
        fill: #f2f3f5;
      }
    }

    /* 激活 */
    &.active {
      z-index: 2;

      .tabs-background {
        opacity: 1;
      }

      .tabs-background-content {
        background-color: #fff;
      }

      .tabs-background-before,
      .tabs-background-after {
        fill: #fff;
      }
    }

    /* 第一个 tab  */
    &:first-of-type {
      .tabs-dividers::before {
        opacity: 0;
      }
    }

    /* 最后一个 tab */
    &:last-of-type {
      .tabs-dividers::after {
        opacity: 0;
      }
    }
  }

  /* tab 标签 */
  .tabs-main {
    align-items: center;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    box-sizing: border-box;
    cursor: pointer;
    display: flex;
    height: 100%;
    left: 0;
    margin: 0 14px;
    overflow: hidden;
    position: absolute;
    right: 0;
    transition: 150ms;
    width: calc(100% - 28px);
  }

  /* 关闭 插槽 */
  .tabs-close {
    cursor: pointer;
    height: 16px;
    position: absolute;
    right: 14px;
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    z-index: 1;
  }

  /* 关闭 icon */
  .tabs-close-icon {
    border-radius: 50%;
    height: 100%;
    width: 100%;

    &:hover {
      background-color: #e8eaed;
      stroke: #000;
    }
  }

  /* tabs-main 中的 label */
  .tabs-label {
    align-items: center;
    box-sizing: border-box;
    display: flex;
    flex: 1;
    justify-content: center;
    margin-left: 7px;
    margin-right: 16px;
    width: calc(100% - 23px);

    .tabs-label-text {
      display: inline-block;
      max-width: calc(100% - 20px);
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    &.no-close {
      margin-right: 7px;
    }

    .tab-name-edit-icon {
      cursor: pointer;
      display: none;
      font-size: 16px;
      margin-left: 2px;
    }

    .tab-lock-icon {
      font-size: 12px;
      margin-left: 5px;
    }

    &:hover {
      .tab-name-edit-icon {
        display: inline-block;
      }
    }
  }

  /* 编辑 */
  .tabs-label-edit {
    width: calc(100% - 23px);
  }

  /* background 背景样式 */
  .tabs-background {
    box-sizing: border-box;
    height: 100%;
    padding: 0 7px - 1px;
    position: absolute;
    transition: opacity 300ms;
    width: 100%;
  }

  .tabs-background-content {
    border-top-left-radius: 7px;
    border-top-right-radius: 7px;
    height: 100%;
    transition: background 150ms;
  }

  .tabs-background-before,
  .tabs-background-after {
    bottom: -1px;
    fill: transparent;
    position: absolute;
    transition: background 150ms;
  }

  .tabs-background-before {
    left: -1px;
  }

  .tabs-background-after {
    right: -1px;
  }

  //.tabs-footer {
  //  background-color: #fff;
  //  height: 4px;
  //}

  .tabs-after {
    display: flex;
    overflow: hidden;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);

    .add-tab {
      align-items: center;
      border-radius: 50%;
      cursor: pointer;
      display: flex;
      height: 24px;
      justify-content: center;
      margin-left: 6px;
      width: 24px;

      .icon-font {
        font-size: 16px;
      }

      &:hover {
        background-color: rgba(184, 186, 191, 0.4);
      }
    }
  }

  @keyframes tab-show {
    from {
      transform: scaleX(0);
    }

    to {
      transform: scaleX(1);
    }
  }
}
</style>
